/******************************************************************************
 * FILE NAME:
 *  queue_main.h
 *
 * DESCRIPTION:
 * This file contains the function for queue message.
 *
 *
 * DESIGN REFERENCE:
 *
 *
 * REVISION HISTORY   :
 * Date            Author               REASON
 * 06.08.2013      Thuan Nguyen         Creation
 *
 * Copyright 2005, NET
 * ***************************************************************************/

#include"../h/queue_def.h"
#include"../h/tp_ap_int_def.h"
#include"../../common/h/syslog_api_platform.h"

extern threads_transport_t *g_threads_list;
U8 g_created_connection_flag;
/***********************************************************************
 * FUNCTION NAME: 
 *  tp_create_tasklist_queues_func
 *
 * DESCRIPTION:
 *	This function will create the message_queue for task_list
 * INPUT: 
 *	request_msg_t *req_msg
 * OUTPUT:
 *	
 * RETURN:
 *	val_result
 * GLOBAL DATA REFERRED:
 *
 * CALLED ROUTINES:
 *
 * NOTES:
 *
 ************************************************************************/
U8 tp_create_tasklist_queues_func()
{
	U8 val_result = SYSLOG_TRUE;
	U32 msgid;
	val_result = msgget((key_t)TASKLIST_MQUEUE, 0666 | IPC_CREAT);
	if( SYSLOG_FAILURE == val_result){
		val_result = SYSLOG_FALSE;
	}
	else{
		SYSLOG_TRANSPORT_INFO_LOGGING("TASKLIST_MQUEUE: Created");
	}
	return val_result;
}


/***********************************************************************
 * FUNCTION NAME: 
 *  tp_create_input_queues_func
 * DESCRIPTION:
 *	create message_queue for transport_input_message_queue
 * INPUT: 
 *
 * OUTPUT:
 *	
 * RETURN:
 *	val_result
 * GLOBAL DATA REFERRED:
 *
 * CALLED ROUTINES:
 *
 * NOTES:
 *
 ************************************************************************/
U8 tp_create_input_queues_func()
{
	U8 val_result = SYSLOG_TRUE;
	U32 msgid;
	val_result = msgget((key_t)TRANSPORT_INPUT_MQUEUE, 0666 | IPC_CREAT);
	if( SYSLOG_FAILURE == val_result){
		val_result = SYSLOG_FALSE;
	}
	else
	{
		SYSLOG_TRANSPORT_INFO_LOGGING("TRANSPORT_INPUT_MQUEUE: Created");
	}
	return val_result;
}


/***********************************************************************
 * FUNCTION NAME: 
 *  tp_monitor_tasklist_queues_func
 * DESCRIPTION:
 *
 * INPUT: 
 *	request_msg_t *req_msg
 * OUTPUT:
 *	
 * RETURN:
 *	val_result
 * GLOBAL DATA REFERRED:
 *
 * CALLED ROUTINES:
 *
 * NOTES:
 *
 ************************************************************************/
void tp_monitor_tasklist_queues_func()
{
	U8 val_result = SYSLOG_FALSE;
	U32 msgid;
	U32 msg_to_receive;
	request_msg_t *msg;
	SYSLOG_TRANSPORT_INFO_LOGGING("Enter function tp_monitor_tasklist_queues_func");
	/*
	msgid = msgget((key_t)TASKLIST_MQUEUE, 0666 | IPC_CREAT);
	if( SYSLOG_FAILURE == msgid)
	{
		SYSLOG_TRANSPORT_ERROR_LOGGING("TASKLIST: msgget failure");
	}
	*/
	while(1)
	{
		msg = (transport_msg_union_t*)T_OS_RECEI_MSG_QUEUE(TASKLIST_MQUEUE);
		/*Receive request on TASKLIST successful.*/
		if(SYSLOG_NULL != msg)
		{
			/*Handle Request*/
			switch(msg->action)
			{
			case OPEN_CONNECTION:
				/*Create a connection between client and server*/
				SYSLOG_TRANSPORT_INFO_LOGGING("MASTER THREAD receive a OPEN_CONNECTION Request " \
											  "socket_id[%d] , client_addr[%s] , port[%d]" \
											  ,msg->socket_id,inet_ntoa(msg->client_addr.sin_addr),\
											  ntohs(msg->client_addr.sin_port));

				val_result = tp_create_connection_thread_func(msg->socket_id,msg->client_addr);
				if(SYSLOG_FALSE == val_result)
				{
					SYSLOG_TRANSPORT_ERROR_LOGGING("Open connection-thread is failure");
				}
				else
				{
					SYSLOG_TRANSPORT_INFO_LOGGING("Open connection-thread is successful");
				}
				break;
			case CLOSE_CONNECTION:
				/*Remove a connection between client and server*/
				SYSLOG_TRANSPORT_INFO_LOGGING("MASTER THREAD receive a CLOSE_CONNECTION Request");
				val_result = tp_rm_connection_thread_func(msg);
				if(SYSLOG_FALSE == val_result)
				{
					SYSLOG_TRANSPORT_ERROR_LOGGING("Close connection-thread is failure");
				}
				else
				{
					SYSLOG_TRANSPORT_INFO_LOGGING("Close connection-thread is successful");
				}
				break;
			default:
				SYSLOG_TRANSPORT_ERROR_LOGGING("MASTER THREAD receive a UNKNOW Request");
				break;
			}
			/*memset and de-allocate req_msg*/
			memset(msg,0,sizeof(request_msg_t));
			T_OS_BLOCK_DEALLOC(TASK_ID_TRANSPORT_TASKLIST,msg);
		}
	}
	SYSLOG_TRANSPORT_INFO_LOGGING("Exit function tp_monitor_tasklist_queues_func");
}
/***********************************************************************
 * FUNCTION NAME: 
 *  tp_monitor_input_queues_func
 * DESCRIPTION:
 *	This function will moniter the input_queue of transport layer.
 *
 * INPUT: 
 *	request_msg_t *req_msg
 * OUTPUT:
 *	
 * RETURN:
 *	val_result
 * GLOBAL DATA REFERRED:
 *
 * CALLED ROUTINES:
 *
 * NOTES:
 *
 ************************************************************************/
void tp_monitor_input_queues_func()
{
	U8 val_result = SYSLOG_FALSE;
	U32 msgid;
	U32 msg_to_receive;
	U8 socket_client = SYSLOG_FAILURE;
	U8 sent_flag = SYSLOG_FAILURE;
	transport_msg_union_t *msg;
	request_msg_t req_msg;
	void *temp_msg;
	SYSLOG_TRANSPORT_INFO_LOGGING("Enter function tp_monitor_input_queues_func");

	while(1)
	{
		g_created_connection_flag = SYSLOG_TRUE;
		msg = (transport_msg_union_t*)T_OS_RECEI_MSG_QUEUE(TRANSPORT_INPUT_MQUEUE);
		if( SYSLOG_NULL != msg)
		{
			/*Encode Header*/

			/*Check connection has exist or not
			 * Case 1: If connection has not existed => send request to tasklist to create a
			 * new connection. Waiting for new connection
			 * 	Small case 1: if new connection create successful => send message on socket_id
			 * 				  of new_connection.
			 * 	Small case 2: if new connection create failure => delete message and
			 * 	writing warning logs.
			 * 	 if g_created_connection_flag = SYSLOG_FALSE => creation of new_connection is
			 * 	 failure
			 * Case 2: If connection has existed => send message based on socket_id of
			 * connection*/

			while(1)
			{

				socket_client = tp_check_connection_from_ll_func(g_threads_list,msg->msg_hdr.dst_addr);
				if(SYSLOG_FAILURE != socket_client)
				{
					/*Case 2: connection has been established*/
					/*Send message base-on socket-id*/
					//write(socket_client,msg->exchange_param.content,sizeof(msg->msg_body.exchange_param.content)+1);
					SYSLOG_TRANSPORT_INFO_LOGGING("Send a message to client with content "\
							"[%s]",msg->msg_body.exchange_param.content);
					SYSLOG_TRANSPORT_INFO_LOGGING("Send a message to client");
					break;
				}
				else
				{
					if(SYSLOG_FALSE == g_created_connection_flag)
					{
						/*Delete message and continue receive message from InputQueue
						 * of Transport.*/
						SYSLOG_TRANSPORT_WARNING_LOGGING("TRANSPORT_INPUT_MQUEUE:Delete messages.");
						break;
					}
					if(SYSLOG_FAILURE == sent_flag)
					{
						/*Case 1: connection hasn't been established
						 *Send request to establish a new connection.
						 * Waiting for new connection
						 * */
						req_msg.msg_id = TRANSPORT_REQ_MSG_ID;
						req_msg.action = OPEN_CONNECTION;
						req_msg.client_addr = msg->msg_hdr.dst_addr;
						req_msg.socket_id = SYSLOG_FAILURE;
						req_msg.reasion = MESSAGE_SEND_FROM_INTPUT_QUEUE;

						/*Send request to TASKLIST*/
						T_OS_SEND_MSG_QUEUE(TASK_ID_TRANSPORT,TASKLIST_MQUEUE,\
											&req_msg,sizeof(request_msg_t));

						SYSLOG_TRANSPORT_INFO_LOGGING("Send a request open connection to TASKLIST");
						/*sent_flag was used for only send connection request 1 time*/
						sent_flag = SYSLOG_SUCCESS;
					}
				}
			}
			socket_client = SYSLOG_FAILURE;
			/*memset and De-allocation resource which was allocated for msg*/
			memset(msg,0,sizeof(transport_msg_union_t));
			T_OS_BLOCK_DEALLOC(TASK_ID_TRANSPORT_INPUTQUEUE,msg);
			sent_flag = SYSLOG_FAILURE;

		}
		else
		{
			SYSLOG_TRANSPORT_ERROR_LOGGING("Receive failure");
		}
	}
	SYSLOG_TRANSPORT_INFO_LOGGING("Exit function tp_monitor_input_queues_func");
}
